package com.app.utils;


import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import com.app.common.SystemConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URL;

/**
 * 添加水印util
 */
@Component
public class WatermarkUtil {

    /**
     * 添加水印
     *
     * @param pictureSourceType 图片来源类型
     * @param watermarkType     水印类型
     * @param path              图片路径
     * @param watermark         水印内容（文字水印内容/图片水印的存放路径）
     * @param targetPath        输出图片存放路径
     * @param x                 x
     * @param y                 y
     */
    public static String addWatermark(PictureSourceType pictureSourceType,
                                      WatermarkType watermarkType,
                                      String path,
                                      String watermark, String targetPath, int x, int y) {
        if (null == pictureSourceType) {
            throw new RuntimeException("图片来源类型不能为空");
        }
        if (null == watermarkType) {
            throw new RuntimeException("水印类型不能为空");
        }
        Image image;
        if (pictureSourceType == PictureSourceType.LOCAL_PICTURE) {
            // 读取本地图片
            image = readLocalPicture(path);
        } else {
            // 读取网络图片
            image = readNetworkPicture(path);
        }
        // 水印处理
        return manageWatermark(image, watermarkType, watermark, targetPath, x, y);
    }

//    /**
//     * 生成邀请码
//     *
//     * @param faceUrl 人脸url
//     * @param codeUrl 代码url
//     * @return {@link String}
//     */
//    public static String generateInvitationCode(String faceUrl, String nickName, String codeUrl) {
//        String out = System.getProperty("user.dir") + File.separator + "/file/style/" + IdUtil.fastSimpleUUID() + ".png";
//        //        写入收款码
//        String template = System.getProperty("user.dir") + File.separator + "/file/templeate/yaoqing.png";
//        String oldCodeUrl = System.getProperty("user.dir") + File.separator + codeUrl;
//        String newWater = addWatermark(PictureSourceType.LOCAL_PICTURE, WatermarkType.IMAGE_WATERMARK, template, oldCodeUrl, out, 115, 450);
//        String faceUrlCodeUrl = System.getProperty("user.dir") + File.separator + faceUrl;
//        String newfaceUrl = System.getProperty("user.dir") + File.separator + "/file/style/" + IdUtil.fastSimpleUUID() + ".png";
//        ImgUtil.scale(
//                FileUtil.file(faceUrlCodeUrl),
//                FileUtil.file(newfaceUrl),
//                150, 150,
//                null
//        );
//        String newFaceUrlWater = addWatermark(PictureSourceType.LOCAL_PICTURE, WatermarkType.IMAGE_WATERMARK, newWater, newfaceUrl, out, 115, 100);
//        String finalOutputAddress = "/file/style/" + IdUtil.fastSimpleUUID() + ".png";
//        String finalOut = System.getProperty("user.dir") + File.separator + finalOutputAddress;
//        addWatermark(PictureSourceType.LOCAL_PICTURE, WatermarkType.TEXT_WATERMARK, newFaceUrlWater, nickName, finalOut, 230, 400);
//        return finalOutputAddress;
//    }
    @Autowired
    private AliyunOSSUtils aliyunOSSUtils;
    /**
     * 生成邀请码
     *
     * @param faceUrl 人脸url
     * @param codeUrl 代码url
     * @return {@link String}
     */
    public  String generateInvitationCode(String faceUrl, String nickName, String codeUrl) {
        try{
            String out = System.getProperty("user.dir") + File.separator + "/file/style/" + IdUtil.fastSimpleUUID() + ".png";
            //写入收款码
            String template = System.getProperty("user.dir") + File.separator + "/file/templeate/yaoqing.png";
            String oldCodeUrl = SystemConstant.DEFAULT_VIEW_URL + codeUrl;

            File oldCodelocalFile = ImgUtils.getFileByHttpURL(oldCodeUrl);

            String newWater = addWatermark(PictureSourceType.LOCAL_PICTURE, WatermarkType.IMAGE_WATERMARK, template, oldCodelocalFile.getAbsolutePath(), out, 115, 450);
            String faceUrlCodeUrl =SystemConstant.DEFAULT_VIEW_URL+  faceUrl;
            File faceUrlCodeFile =ImgUtils.getFileByHttpURL(faceUrlCodeUrl);
            String newfaceUrl = System.getProperty("user.dir") + File.separator + "/file/style/" + IdUtil.fastSimpleUUID() + ".png";
            ImgUtil.scale(
                    faceUrlCodeFile,
                    FileUtil.file(newfaceUrl),
                    150, 150,
                    null
            );
            String newFaceUrlWater = addWatermark(PictureSourceType.LOCAL_PICTURE, WatermarkType.IMAGE_WATERMARK, newWater, newfaceUrl, out, 115, 100);
            String finalOutputAddress = "file/style/" + IdUtil.fastSimpleUUID() + ".png";
            String finalOut = System.getProperty("user.dir") + File.separator + finalOutputAddress;
            addWatermark(PictureSourceType.LOCAL_PICTURE, WatermarkType.TEXT_WATERMARK, newFaceUrlWater, nickName, finalOut, 230, 400);
            aliyunOSSUtils.objectStorageUploadFile(finalOutputAddress,FileUtil.getInputStream(finalOut));
            try{
                FileUtil.del(finalOut);
                FileUtil.del(faceUrlCodeFile);
                FileUtil.del(oldCodelocalFile);
                FileUtil.del(FileUtil.file(newfaceUrl));
                FileUtil.del(FileUtil.file(out));
            }catch (Exception e)
            {
                System.out.println("文件删除失败");
            }
            return finalOutputAddress;
        }catch (Exception e)
        {
            e.printStackTrace();
        }
        return "";
    }





    /**
     * 生成收款代码
     *
     * @return {@link String}
     */
    public  String generateCollectionCode(String faceUrl, String nickName, String codeUrl) {
        try{
            String out = System.getProperty("user.dir") + File.separator + "/file/style/" + IdUtil.fastSimpleUUID() + ".png";
            //        写入收款码
            String template = System.getProperty("user.dir") + File.separator + "/file/templeate/shoukuan.png";

            String oldCodeUrl = SystemConstant.DEFAULT_VIEW_URL + codeUrl;
            File oldCodelocalFile = ImgUtils.getFileByHttpURL(oldCodeUrl);

            String newWater = addWatermark(PictureSourceType.LOCAL_PICTURE, WatermarkType.IMAGE_WATERMARK, template,  oldCodelocalFile.getAbsolutePath(), out, 115, 275);
            String faceUrlCodeUrl =SystemConstant.DEFAULT_VIEW_URL+  faceUrl;
            File faceUrlCodeFile =ImgUtils.getFileByHttpURL(faceUrlCodeUrl);
            String newfaceUrl = System.getProperty("user.dir") + File.separator + "/file/style/" + IdUtil.fastSimpleUUID() + ".png";
            ImgUtil.scale(
                    faceUrlCodeFile,
                    FileUtil.file(newfaceUrl),
                    150, 150,
                    null
            );
            String newFaceUrlWater = addWatermark(PictureSourceType.LOCAL_PICTURE, WatermarkType.IMAGE_WATERMARK, newWater, newfaceUrl, out, 115, 135);
            String finalOutputAddress = "file/style/" + IdUtil.fastSimpleUUID() + ".png";
            String finalOut = System.getProperty("user.dir") + File.separator + finalOutputAddress;
            addWatermark(PictureSourceType.LOCAL_PICTURE, WatermarkType.TEXT_WATERMARK, newFaceUrlWater, nickName, finalOut, 230, 500);
            aliyunOSSUtils.objectStorageUploadFile(finalOutputAddress,FileUtil.getInputStream(finalOut));
            try{
                FileUtil.del(finalOut);
                FileUtil.del(faceUrlCodeFile);
                FileUtil.del(oldCodelocalFile);
                FileUtil.del(FileUtil.file(newfaceUrl));
                FileUtil.del(FileUtil.file(out));
            }catch (Exception e)
            {
                System.out.println("文件删除失败");
            }
            return finalOutputAddress;
        }catch (Exception e)
        {

        }
        return "";
    }

    //图片来源类型枚举
    public enum PictureSourceType {
        //本地图片
        LOCAL_PICTURE,
        //网络图片
        NETWORK_PICTURE;
    }

    //水印类型枚举
    public enum WatermarkType {
        //文字水印
        TEXT_WATERMARK,
        //图片水印
        IMAGE_WATERMARK;
    }

    /**
     * 读取本地图片
     *
     * @param path 本地图片存放路径
     */
    public static Image readLocalPicture(String path) {
        if (null == path) {
            throw new RuntimeException("本地图片路径不能为空");
        }
        // 读取原图片信息 得到文件
        File srcImgFile = new File(path);
        try {
            // 将文件对象转化为图片对象
            return ImageIO.read(srcImgFile);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 读取网络图片
     *
     * @param path 网络图片地址
     */
    public static Image readNetworkPicture(String path) {
        if (null == path) {
            throw new RuntimeException("网络图片路径不能为空");
        }
        try {
            // 创建一个URL对象,获取网络图片的地址信息
            URL url = new URL(path);
            // 将URL对象输入流转化为图片对象 (url.openStream()方法，获得一个输入流)
            BufferedImage bugImg = ImageIO.read(url.openStream());
            if (null == bugImg) {
                throw new RuntimeException("网络图片地址不正确");
            }
            return bugImg;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 水印处理
     *
     * @param image         图片对象
     * @param watermarkType 水印类型（1-文字水印 2-图片水印）
     * @param watermark     水印内容（文字水印内容/图片水印的存放路径）
     * @param tarImgPath    输出图片存放路径
     * @param x             x
     * @param y             y
     */
    public static String manageWatermark(Image image,
                                         WatermarkType watermarkType,
                                         String watermark,
                                         String tarImgPath,
                                         int x,
                                         int y) {
        int imgWidth = image.getWidth(null);
        int imgHeight = image.getHeight(null);
        BufferedImage bufImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);
        // 加水印,创建画笔
        Graphics2D graphics = bufImg.createGraphics();
        // 绘制原始图片
        graphics.drawImage(image, 0, 0, imgWidth, imgHeight, null);

        // 校验水印的类型
        if (watermarkType == WatermarkType.TEXT_WATERMARK) {
            if (watermark.isEmpty()) {
                throw new RuntimeException("文字水印内容不能为空");
            }
            // 添加文字水印：
            // 根据图片的背景设置水印颜色
            graphics.setColor(Color.BLACK);
            // 设置字体  画笔字体样式为微软雅黑，加粗，文字大小为45pt
            graphics.setFont(new Font("微软雅黑", Font.BOLD, 45));
            // 设置水印的坐标(为原图片中间位置)
            // 画出水印 第一个参数是水印内容，第二个参数是x轴坐标，第三个参数是y轴坐标
            x = (imgWidth - getWatermarkLength(watermark, graphics)) / 2;
//            y = imgHeight / 2;
            graphics.drawString(watermark, x, y);
            graphics.dispose();
        } else {
            // 添加图片水印：
            if (watermark.isEmpty()) {
                throw new RuntimeException("图片水印存放路径不能为空");
            }
            Image srcWatermark = readLocalPicture(watermark);
            int watermarkWidth = srcWatermark.getWidth(null);
            int watermarkHeight = srcWatermark.getHeight(null);
            // 设置 alpha 透明度：alpha 必须是范围 [0.0, 1.0] 之内（包含边界值）的一个浮点数字
            graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.9f));
            // 绘制水印图片  坐标为中间位置
            x = (imgWidth - watermarkWidth) / 2;
            graphics.drawImage(srcWatermark, x, y * 2, watermarkWidth, watermarkHeight, null);
            graphics.dispose();
        }
        // 输出图片
        try {
            FileOutputStream outImgStream = new FileOutputStream(tarImgPath);
            ImageIO.write(bufImg, "png", outImgStream);
            outImgStream.flush();
            outImgStream.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return tarImgPath;
    }

    /**
     * 获取水印文字的长度
     *
     * @param watermarkContent 文字水印内容
     * @param graphics         图像类
     */
    private static int getWatermarkLength(String watermarkContent, Graphics2D graphics) {
        return graphics.getFontMetrics(graphics.getFont()).charsWidth(watermarkContent.toCharArray(), 0, watermarkContent.length());
    }

}

